package com.michael.ims.admin.controller;

import com.michael.ims.admin.controller.io.role.*;
import com.michael.ims.app.QTblRight;
import com.michael.ims.app.QTblRole;
import com.michael.ims.app.QTblRoleToRight;
import com.michael.ims.app.QTblSystem;
import com.michael.io.*;
import com.michael.plugins.PageHelper;
import com.querydsl.core.types.Projections;
import com.querydsl.sql.SQLQuery;
import com.querydsl.sql.SQLQueryFactory;
import com.querydsl.sql.dml.SQLInsertClause;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;

@Api(tags = "角色管理")
@RestController
@RequestMapping("/role")
public class RoleController {

    @Autowired
    private SQLQueryFactory sqlQueryFactory;

    @ApiOperation("添加角色")
    @PostMapping("/add")
    @Transactional
    public RespStatus addRole(@RequestBody @Valid AddRoleReq req) {
        QTblRole tblRole = QTblRole.tblRole;
        sqlQueryFactory.insert(tblRole)
                .set(tblRole.name, req.getName())
                .set(tblRole.systemId, req.getSystemId())
                .set(tblRole.description, req.getDescription())
                .set(tblRole.genTime, LocalDate.now())
                .execute();
        return new RespStatus();
    }

    @ApiOperation("修改角色")
    @PostMapping("/modify")
    @Transactional
    public RespStatus modifyRole(@RequestBody @Valid ModifyRoleReq req) {
        QTblRole tblRole = QTblRole.tblRole;
        sqlQueryFactory.update(tblRole)
                .set(tblRole.name, req.getName())
                .set(tblRole.systemId, req.getSystemId())
                .set(tblRole.description, req.getDescription())
                .set(tblRole.genTime, LocalDate.now())
                .where(tblRole.id.eq(req.getId()))
                .execute();
        return new RespStatus();
    }

    @ApiOperation("删除角色")
    @GetMapping("/delete/{roleId}")
    @Transactional
    public RespStatus delRole(@PathVariable("roleId") Long roleId) {
        QTblRole tblRole = QTblRole.tblRole;
        sqlQueryFactory.delete(tblRole)
                .where(tblRole.id.eq(roleId))
                .execute();
        return new RespStatus();
    }

    @ApiOperation("角色列表")
    @PostMapping("/query")
    @Transactional
    public RespData<RespPageBody<QueryRoleVO>> query(@RequestBody @Valid ReqPage<QueryRoleCond> req) {
        PageHelper.Page<QueryRoleVO> page = PageHelper.buildPage(req.getPage());

        QueryRoleCond condition = req.getCondition();
        QTblRole tblRole = QTblRole.tblRole;
        QTblSystem tblSystem = QTblSystem.tblSystem;
        SQLQuery<QueryRoleVO> sqlQuery = sqlQueryFactory.select(Projections.bean(QueryRoleVO.class, tblRole.id, tblRole.systemId, tblSystem.name.as("systemName"),
                tblRole.name, tblRole.description, tblRole.genTime))
                .from(tblRole).join(tblSystem)
                .where(tblRole.systemId.eq(tblSystem.id));
        if (condition.getSystemId() != null) {
            sqlQuery.where(tblRole.systemId.eq(condition.getSystemId()));
        }
        if (StringUtils.isNotBlank(condition.getName())) {
            sqlQuery.where(tblRole.name.contains(condition.getName()));
        }
        PageHelper.execute(sqlQuery);

        RespPageBody<QueryRoleVO> body = new RespPageBody<>();
        body.setData(page.getData());
        body.setPage(page.getPage());

        RespData<RespPageBody<QueryRoleVO>> resp = new RespData<>();
        resp.setBody(body);
        return resp;
    }

    @ApiOperation("权限查询")
    @PostMapping("/right/query")
    @Transactional
    public RespData<RespPageBody<RightVO>> queryRights(@RequestBody @Valid ReqPage<QueryRightByRoleReq> req) {
        QueryRightByRoleReq condition = req.getCondition();
        PageHelper.Page<RightVO> page = PageHelper.buildPage(req.getPage());
        QTblSystem tblSystem = QTblSystem.tblSystem;
        QTblRoleToRight tblRoleToRight = QTblRoleToRight.tblRoleToRight;
        QTblRight tblRight = QTblRight.tblRight;
        SQLQuery<RightVO> sqlQuery = sqlQueryFactory.select(Projections.bean(RightVO.class, tblRoleToRight.id, tblRight.isMenu, tblRight.name, tblRight.description))
                .from(tblRight).join(tblRoleToRight).join(tblSystem)
                .where(tblRight.id.eq(tblRoleToRight.rightId)
                        .and(tblRight.systemId.eq(tblSystem.id))
                        .and(tblSystem.isDelete.isFalse())
                        .and(tblRoleToRight.roleId.eq(condition.getRoleId()))
                        .and(tblRoleToRight.systemId.eq(condition.getSystemId())));
        PageHelper.execute(sqlQuery);

        RespPageBody<RightVO> body = new RespPageBody<>();
        body.setPage(page.getPage());
        body.setData(page.getData());
        RespData<RespPageBody<RightVO>> resp = new RespData<>();
        resp.setBody(body);
        return resp;
    }

    @ApiOperation("给角色赋予权限")
    @PostMapping("/right/add")
    @Transactional
    public RespStatus addRights(@RequestBody @Valid AddRightReq req) {
        QTblRoleToRight tblRoleToRight = QTblRoleToRight.tblRoleToRight;
        sqlQueryFactory.insert(tblRoleToRight)
                .set(tblRoleToRight.rightId, req.getRightId())
                .set(tblRoleToRight.roleId, req.getRoleId())
                .set(tblRoleToRight.systemId, req.getSystemId())
                .execute();
        return new RespStatus();
    }

    @ApiOperation("去掉角色权限")
    @GetMapping("/right/delete/{id}")
    @Transactional
    public RespStatus deleteRights(@PathVariable("id") Long id) {
        QTblRoleToRight tblRoleToRight = QTblRoleToRight.tblRoleToRight;
        sqlQueryFactory.delete(tblRoleToRight)
                .where(tblRoleToRight.id.eq(id))
                .execute();
        return new RespStatus();
    }

    @ApiOperation("指定系统下角色列表")
    @GetMapping("/system/list/{systemId}")
    @Transactional
    public RespData<List<ListRolesResp>> list(@PathVariable("systemId") Integer systemId) {
        QTblRole tblRole = QTblRole.tblRole;
        List<ListRolesResp> data = sqlQueryFactory.select(Projections.bean(ListRolesResp.class, tblRole.id, tblRole.name))
                .from(tblRole)
                .where(tblRole.systemId.eq(systemId))
                .fetch();
        return new RespData<>(data);
    }
}
